//
//  UIScrollView+Refresh.m
//  Common
//
//  Created by guoshiqing on 2018/6/15.
//  Copyright © 2018年 www.bitkinetic.com. All rights reserved.
//


#import "UIScrollView+Refresh.h"


#import "MJRefreshBackNormalFooter.h"
#import "ERefreshHeader.h"
#import "ERefreshFooter.h"
#import "MJRefreshComponent+Refresh.h"
#import "NSObject+Swizzle.h"

static NSString *const CTRefreshFooterStateStateIdle = @"加载中";
static NSString *const CTRefreshFooterStateRefreshing = @"查看更多";
static NSString *const CTRefreshFooterStateNoMoreData = @"没有更多的数据了";

//static NSInteger const kRefreshDefatultNewRowNum=20;

static Class ctRefreshHeaderClass = nil;
static Class ctRefreshFooterClass = nil;


@interface UIScrollView ()
@property (nonatomic,assign)NSInteger cellCount;

@end
@implementation UIScrollView (Refresh)
+ (void)load
{
    ctRefreshHeaderClass = [ERefreshHeader class];
    ctRefreshFooterClass = [ERefreshFooter class];
    
    [UITableView swizzleMethod:@selector(reloadData) withMethod:@selector(reloadData) error:nil];
}

- (void)reloadData
{
    if(!self.isUseAutoRefresh || ![self isKindOfClass:[UITableView class]])
    {
        [self reloadData];
        return;
    }
    if (!self.header&&!self.footer) {
        [self reloadData];
        return;
    }
    if (self.header.cancelAutoChangeStatu&&self.footer.cancelAutoChangeStatu) {
        [self reloadData];
        return;
    }
    NSInteger lastCount = self.totalDataCount;
    [self reloadData];
    //刷新数据前后
    if (!self.footer.cancelAutoChangeStatu) {
        [self hiddenFootByContentHeight];//头部刷新的时候也要判断，是否显示脚
    }

    if (self.header&&!self.header.cancelAutoChangeStatu) {
        //如果正在刷新则停止头部刷新
        if (self.header.isRefreshing) {
            [self headerEndRefreshing];
        }
        //如果是无动画的刷新，也要回复状态
        self.isHeaderExcuting = NO;
        self.isHeaderRefreshError = NO;
    }
    if (self.footer&&[self.footer isRefreshing]&&!self.footer.cancelAutoChangeStatu) {
        NSInteger newCount=self.totalDataCount;
        //由于服务端的要求，不能每次准确的返回20条数据，所以这里 改成了只判断是否有新增数据，有新增都可以继续下拉
        lastCount<newCount? [self footerEndRefreshing:(lastCount-newCount)]:[self footerEndRefreshNoMoreDate];
    }

}

+ (void)setRefreshHeaderClass:(Class)headerClass footerClass:(Class)footerClass
{
    if (headerClass) {
        ctRefreshHeaderClass = headerClass;
    }
    if (footerClass) {
        ctRefreshFooterClass = footerClass;
    }
}
#pragma mark - header methods
- (void)addHeaderWithRefreshingBlock:(void (^)())block
{
    if (block == nil) {
        self.header = nil;
        return;
    }
    
    if ([self.header isKindOfClass:ctRefreshHeaderClass])
    {
        self.header.refreshingBlock = block;
    }
    else
    {
        self.header = [ctRefreshHeaderClass headerWithRefreshingBlock:block];
        self.header.automaticallyChangeAlpha = NO;
        [self headerSetting];
    }
}
- (void)addHeaderWithRefreshingSubHeadClass:(Class )subHeaderClass Block:(void (^)())block//自定义的头部
{
    if (block == nil) {
        self.header = nil;
        return;
    }
   
        self.header = [subHeaderClass headerWithRefreshingBlock:block];
        self.header.automaticallyChangeAlpha = NO;
        [self headerSetting];

}
- (void)addHeaderWithRefreshingTarget:(id)target action:(SEL)action
{
    if ([self.header isKindOfClass:ctRefreshHeaderClass])
    {
        [self.header setRefreshingTarget:target refreshingAction:action];
    }
    else
    {
        self.header = [ctRefreshHeaderClass headerWithRefreshingTarget:target refreshingAction:action];
        self.header.automaticallyChangeAlpha = NO;
        [self headerSetting];
    }
}

- (void)headerBeginRefreshing
{
    if (self.header.state == MJRefreshStateRefreshing)
    {
        return;
    }
    if (!self.footer.cancelAutoChangeStatu) {
        //刷新的时候要重置脚的状态
        [self.footer resetNoMoreData];
    }
    
    if (self.showPullAnimation&&!self.isHeaderExcuting) {
        [self.header beginRefreshing];
    }
    else
    {
        [self.header executeRefreshingCallback];
        self.isHeaderExcuting=YES;
    }
    self.showPullAnimation++;
}
- (void)headerBeginRefreshingWithNoPullAnimation
{
    self.showPullAnimation=0;
    [self headerBeginRefreshing];
}
- (void)headerEndRefreshing
{
    //头部刷新结束来重置底部比较靠谱
    if (!self.footer.cancelAutoChangeStatu) {
        [self.footer resetNoMoreData];
    }
//    这里会做刷新文字显示，延迟1秒结束刷新动画
    [((ERefreshHeader *)self.header) endRefreshingWithRetunResultSucceed:!self.isHeaderRefreshError];
}
- (BOOL)headerIsRefreshing
{
    return self.header.isRefreshing;
}
- (void)headerHidden:(BOOL)hidden
{
    self.header.hidden = hidden;
}
- (id)getHeaderView
{
    return self.header;
}

#pragma mark - Footer methods

- (void)addFooterWithMoreBlock:(void (^)())block
{
    if (block == nil) {
        self.footer = nil;
        return;
    }
    
    if ([self.footer isKindOfClass:ctRefreshFooterClass])
    {
        self.footer.refreshingBlock = block;
    }
    else
    {
        self.footer = [ctRefreshFooterClass footerWithRefreshingBlock:block];
        self.footer.automaticallyChangeAlpha = NO;
        self.footer.automaticallyHidden = NO;
        [self footerSetting];
    }
}

- (void)addfooterWithMoreTarger:(id)target action:(SEL)action
{
    if ([self.footer isKindOfClass:ctRefreshFooterClass])
    {
        [self.footer setRefreshingTarget:target refreshingAction:action];
    }
    else
    {
        self.footer = [ctRefreshFooterClass footerWithRefreshingTarget:target refreshingAction:action];
        self.footer.automaticallyChangeAlpha = NO;
        self.footer.automaticallyHidden = NO;
        [self footerSetting];
    }
}

- (void)footerBeginRefreshing
{
    if (self.footer.state == MJRefreshStateRefreshing)
    {
        return;
    }
    [self.footer beginRefreshing];
}
- (BOOL)footerIsRefreshing
{
    return self.footer.isRefreshing;
    
}
- (void)footerEndRefreshing:(NSInteger)listCount
{
    [(ERefreshFooter*)self.footer endFooterRefreshingWithResult:listCount> 20 ? 1: 2];
    [self hiddenFootByContentHeight];//需要在停止以后调用
}

- (void)footerEndRefreshing
{
    [self.footer endRefreshing];
    [self hiddenFootByContentHeight];//需要在停止以后调用
}
- (void)footerEndRefreshNoMoreDate
{
    BOOL isUnlimit=  [[self.footer valueForKey:@"isUnlimitedFoot"] integerValue];
    if (isUnlimit) {
        [self.footer endRefreshing];
    }
    else
    {
        [(ERefreshFooter*)self.footer endFooterRefreshingWithResult:3];
        [self.footer endRefreshingWithNoMoreData];

    }
    [self hiddenFootByContentHeight];
}
//如果数据不足够一个页面的，不显示加载更多
//,ignoreHieght,因为CollecionView没有footerView之类的设定，通常会用cell设置没有任何数据的界面，所以添加上ignoreHeight,来忽略底部foot高度
- (void)hiddenFootByContentHeight
{
    
    BOOL isUnlimit = [[self.footer valueForKey:@"isUnlimitedFoot"] integerValue];
    if ( isUnlimit) {//无限加载的模式
        [self.footer setHidden:NO];
        return;
    }
    CGFloat realContentHight=self.mj_contentH;
    if ([self isKindOfClass:[UITableView class]]) {
        UITableView *selfTableView=(UITableView *)self;
        UIView *headView = selfTableView.tableHeaderView;
        UIView *footView =selfTableView.tableFooterView;
        realContentHight -= headView.frame.size.height;
        realContentHight -= footView.frame.size.height;
    }
    if (self.placeholderHeight) {
        realContentHight -= self.placeholderHeight;
    }
    else if ([self isKindOfClass:[UICollectionView class]])
    {
        UICollectionView *selfTableView = (UICollectionView *)self;
        UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)selfTableView.collectionViewLayout;
        if (layout) {
            realContentHight -= layout.headerReferenceSize.height;
            realContentHight -= layout.footerReferenceSize.height;
        }

    }
    //列表高度小于视图高度的时候，不要显示刷新脚。数据太少也不显示。（允许64的留白）
    if (realContentHight + 64 < self.mj_h&&self.totalDataCount < self.refreshDefatultNewRowNum) {
        [self.footer setHidden:YES];
    }
    else
    {
        [self.footer setHidden:NO];
    }
}
- (void)resetFootStatus
{
    [self.footer resetNoMoreData];
}
- (void)footerHidden:(BOOL)hidden
{
    self.footer.hidden = hidden;
}

- (void)endRefreshAndLoadMore
{
    [self headerEndRefreshing];
    [self footerEndRefreshing];
}
- (id)getFooterView
{
    return self.footer;
}

#pragma mark - 内部方法

- (void)headerSetting
{
    MJRefreshStateHeader* header = (id)self.header;
    if ([header respondsToSelector:@selector(setTitle:forState:)]) {
        [header setTitle:@"" forState:MJRefreshStateIdle];
        [header setTitle:@"" forState:MJRefreshStatePulling];
        [header setTitle:@"" forState:MJRefreshStateRefreshing];

    }
    if ([header respondsToSelector:@selector(stateLabel)]) {
        header.stateLabel.font = [UIFont systemFontOfSize:12];
    }
}

- (void)footerSetting
{
    MJRefreshBackStateFooter* footer = (id)self.footer;
    if ([footer respondsToSelector:@selector(setTitle:forState:)]) {
        [footer setTitle:CTRefreshFooterStateStateIdle forState:MJRefreshStateIdle];
        [footer setTitle:CTRefreshFooterStateRefreshing forState:MJRefreshStateRefreshing];
        [footer setTitle:CTRefreshFooterStateNoMoreData forState:MJRefreshStateNoMoreData];
    }
    if ([footer respondsToSelector:@selector(stateLabel)]) {
        footer.stateLabel.font = [UIFont systemFontOfSize:12];
    }
}

//页面刷新时间
- (NSDate*)getRefreshTime
{
    MJRefreshHeader* header =  (MJRefreshHeader*)[self getHeaderView];
    return   header.lastUpdatedTime;
}
#pragma mark propertys

- (NSInteger)totalDataCount
{
    return  self.totalDataCount;
}

- (void)setCanAutoLoadMore:(BOOL)canAutoLoadMore
{
    objc_setAssociatedObject(self, @selector(canAutoLoadMore), [NSNumber numberWithBool:canAutoLoadMore], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)canAutoLoadMore
{
    NSNumber *loadMore = objc_getAssociatedObject(self, @selector(canAutoLoadMore));
    BOOL canAutoLoadMore= [loadMore integerValue];
    return canAutoLoadMore;
}

- (void)setShowPullAnimation:(NSInteger)showPullAnimation
{
    objc_setAssociatedObject(self, @selector(showPullAnimation), [NSNumber numberWithBool:showPullAnimation], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)showPullAnimation
{
    NSNumber *isFirstPull = objc_getAssociatedObject(self, @selector(showPullAnimation));
    NSInteger pullBool= [isFirstPull integerValue];
    return pullBool;
}
- (void)setIsHeaderExcuting:(BOOL)isHeaderExcuting
{
    objc_setAssociatedObject(self, @selector(isHeaderExcuting), [NSNumber numberWithBool:isHeaderExcuting], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isHeaderExcuting
{
    NSNumber *loadMore = objc_getAssociatedObject(self, @selector(isHeaderExcuting));
    BOOL isHeaderExcuting= [loadMore integerValue];
    return isHeaderExcuting;
}

- (void)setIsHeaderRefreshError:(BOOL)isHeaderRefreshError
{
    objc_setAssociatedObject(self, @selector(isHeaderRefreshError), [NSNumber numberWithBool:isHeaderRefreshError], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isHeaderRefreshError
{
    NSNumber *loadMore = objc_getAssociatedObject(self, @selector(isHeaderRefreshError));
    BOOL isHeaderRefreshError= [loadMore integerValue];
    return isHeaderRefreshError;
}


- (void)setIsUseAutoRefresh:(BOOL)isUseAutoRefresh
{
    objc_setAssociatedObject(self, @selector(isUseAutoRefresh), [NSNumber numberWithBool:isUseAutoRefresh], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isUseAutoRefresh
{
    NSNumber *loadMore = objc_getAssociatedObject(self, @selector(isUseAutoRefresh));
    BOOL isUseAutoRefresh= [loadMore integerValue];
    return isUseAutoRefresh;
}


- (void)setRefreshDefatultNewRowNum:(NSInteger)refreshDefatultNewRowNum
{
    objc_setAssociatedObject(self, @selector(refreshDefatultNewRowNum), [NSNumber numberWithInteger:refreshDefatultNewRowNum], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)refreshDefatultNewRowNum
{
    NSNumber *isFirstPull = objc_getAssociatedObject(self, @selector(refreshDefatultNewRowNum));
    NSInteger pullBool= [isFirstPull integerValue];
    if (pullBool <= 0) {
        pullBool = 20;
    }
    return pullBool;
}


- (void)setCellCount:(NSInteger)cellCount
{
    objc_setAssociatedObject(self, @selector(cellCount), [NSNumber numberWithBool:cellCount], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)cellCount
{
    NSNumber *isFirstPull = objc_getAssociatedObject(self, @selector(cellCount));
    NSInteger pullBool= [isFirstPull integerValue];
    return pullBool;
}

- (void)setplaceholderHeight:(CGFloat)placeholderHeight
{
    objc_setAssociatedObject(self, @selector(placeholderHeight), @(placeholderHeight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGFloat)placeholderHeight
{
    NSNumber *isFirstPull = objc_getAssociatedObject(self, @selector(placeholderHeight));
    NSInteger pullBool= [isFirstPull floatValue];
    return pullBool;
}
@end
